let activeEffect = null; // 用于存储当前活跃的依赖函数
const depsMap = new Map(); // 用于存储依赖关系
const effectStack = []; // 用于存储依赖函数的栈
/**
 *
 * @param {*} target
 * @param {*} key
 * @description 依赖收集函数
 */
function track(target, key) {
  // 建立依赖关系
  if (activeEffect) {
    let deps = depsMap.get(key);
    if (!deps) {
      deps = new Set(); // 创建一个新的 Set 来存储依赖函数
      depsMap.set(key, deps);
    }
    deps.add(activeEffect); // 将当前活跃的依赖函数添加到 Set 中
    activeEffect.deps.push(deps); // 记录依赖函数在哪些属性的集合中
  }

  console.log(depsMap);
}

function trigger(target, key) {
  const deps = depsMap.get(key); // 获取与 key 相关的依赖函数集合
  if (deps) {
    // deps.forEach((effectFn) => {
    //   // console.log(`触发依赖更新: ${key}，${effectFn}`);
    //   effectFn();
    // }); // 遍历集合并执行每个依赖函数
    const newDeps = new Set(deps); // 创建一个新的 Set 来避免在迭代过程中修改原集合
    newDeps.forEach((effectFn) => {
      // console.log(`触发依赖更新: ${key}，${effectFn}`);
      effectFn(); // 执行依赖函数
    });
  }
}

const data = {
  a: 1,
  b: 2,
  c: 3,
};

const state = new Proxy(data, {
  get(target, key) {
    track(target, key); // 依赖收集
    return Reflect.get(target, key);
  },
  set(target, key, value) {
    target[key] = value;
    trigger(target, key); // 通知依赖更新
    return true;
  },
});

function cleanup(effectFn) {
  let deps = effectFn.deps; // 获取依赖函数的依赖数组
  if (deps) {
    deps.forEach((dep) => {
      dep.delete(effectFn); // 从每个依赖集合中删除当前依赖函数
      if (dep.size === 0) {
        for (let [key, value] of depsMap) {
          if (value === dep) {
            depsMap.delete(key); // 如果集合为空，则从 depsMap 中删除该集合
          }
        }
      }
    });

    deps.length = 0; // 清空依赖函数的依赖数组
  }
}

/**
 *
 * @param {*} fn 依赖函数
 */
function effect(fn) {
  const environment = () => {
    activeEffect = environment; // 设置当前活跃的依赖函数
    effectStack.push(environment); // 将当前依赖函数压入栈中
    // 清理之前的依赖函数
    cleanup(environment);
    fn(); // 执行依赖函数
    // activeEffect = null; // 清除活跃的依赖函数
    effectStack.pop(); // 从栈中弹出当前依赖函数
    activeEffect = effectStack[effectStack.length - 1] || null; // 恢复上一个活跃的依赖函数
  };
  environment.deps = []; // 初始化依赖数组,用来记录这个环境函数在哪些属性的集合中
  environment(); // 立即执行一次依赖函数
}

// effect(() => {
//   console.log("执行函数");
//   console.log(state.a);
// });
// ===================================================
// effect(() => {
//   if (state.a === 1) {
//     state.b;
//   } else {
//     state.c;
//   }

//   console.log("执行了函数");
// });
// state.a = 10; // 修改 state.a 的值，触发依赖更新

// effect(() => {
//   if (state.a === 1) {
//     state.b;
//   } else {
//     state.c;
//   }
//   console.log("执行了函数1");
// });
// effect(() => {
//   console.log(state.c);
//   console.log("执行了函数2");
// });
// state.a = 2;

// effect(() => {
//   if (state.a === 1) {
//     state.b;
//   } else {
//     state.c;
//   }
//   console.log("执行了函数1");
// });
// effect(() => {
//   console.log(state.a);
//   console.log(state.c);
//   console.log("执行了函数2");
// });
// state.a = 2;

effect(() => {
  effect(() => {
    state.a;
    console.log("执行了函数2");
  });
  state.b;
  console.log("执行了函数1");
});
